package per.dj.testpro.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import per.dj.testpro.entity.protocol.*;
import per.dj.testpro.service.AckService;
import per.dj.testpro.service.BaseService;
import per.dj.testpro.utils.CommonUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class AckServiceImpl extends BaseServiceImpl implements AckService{

    private final static Logger LOGGER = LoggerFactory.getLogger(AckServiceImpl.class);

    private ConcurrentLinkedQueue<Message> dataQueue = new ConcurrentLinkedQueue<Message>();

    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(50);

    private Thread processRealDataThread;

    private Boolean startProcess = true;

    public AckServiceImpl() {
        processRealDataThread = new Thread(new Runnable() {
            public void run() {
                ProcessRealDataThreadFunc();
            }
        });
        processRealDataThread.start();
    }

    public void beginAck(Message tm) {
        dataQueue.add(tm);
    }

    private void ProcessRealDataThreadFunc() {

        while (startProcess) {
            try {
                Message tm = dataQueue.poll();//从队列中删除第一个元素
                final List<Message> msgList = new ArrayList<Message>();
                while (tm != null) {
                    msgList.add(tm);
                    if (msgList.size() > 100)
                        break;
                    tm = dataQueue.poll();
                }
                if (msgList.size() > 0) {
                    LOGGER.info("Ack中List大小:" + msgList.size());
                    fixedThreadPool.execute(new Runnable() {
                        @Override
                        public void run() {
                            SendGeneralAck(msgList);
                        }
                    });
                }
            } catch (Exception ex) {
                LOGGER.error(ex.getMessage(), ex);
                continue;
            }

            try {
                Thread.sleep(20L);
            } catch (InterruptedException e1) {
                LOGGER.error(e1.getMessage(), e1);
                continue;
            }
        }
    }

    private void SendGeneralAck(List<Message> msgList) {
        for (Message tm : msgList) {
            SendGeneralAck(tm);
        }
    }

    private void SendGeneralAck(Message msg) {
        int msgId = msg.getHeader().getMessageId();
        if (msgId == 0)
            return;
        LOGGER.info("命令号:" + msg.getHeader().getMessageId() + "-------设备id:" + msg.getHeader().getSimId());
        String simId = msg.getHeader().getSimId();
        LOGGER.info(simId + ":" + msgId);
        // 终端注册
        if (msgId == 0x01) {
            terminalRegister(msg);
        // 终端登录
        }else if(msgId == 0x02){
            terminalLogin(msg);
        // 终端对时
        }else if(msgId == 0x03){
            terminalTime(msg);
        //终端心跳
        }else if(msgId == 0x04){
            terminalHeart(msg);
        //开始充电
        }else if(msgId == 0x08){
            terminalStartTrans(msg);
        //结束
        }else if(msgId == 0x09){
            terminalEndTrans(msg);
        //结束
        }else if(msgId == 0x0B){
            terminalErrorUpdate(msg);
        }
    }

    private void terminalErrorUpdate(Message msg){
        int res = 0;
        Qy_0B qy0b = (Qy_0B)msg.getMessageContents();

        Res_0B res0b = new Res_0B();
        res0b.setUpdateErrRes((byte)res);

        Message ts = new Message();
        ts.setMessageContents(res0b);
        ts.setHeader(new MessageHeader());
        ts.getHeader().setMessageId(0x0B);
        ts.getHeader().setSimId(msg.getHeader().getSimId());
        ts.getHeader().setMessageSize(13);
        ts.getHeader().setMessageSerialNo(msg.getHeader().getMessageSerialNo());
        send(ts);
    }
    private void terminalEndTrans(Message msg){
        int res = 0;
        Qy_09 qy09 = (Qy_09)msg.getMessageContents();

        Res_09 res09 = new Res_09();
        res09.setEndRes((byte)res);
        res09.setTransactionSerialNumber(qy09.getTransactionSerialNumber());

        Message ts = new Message();
        ts.setMessageContents(res09);
        ts.setHeader(new MessageHeader());
        ts.getHeader().setMessageId(0x09);
        ts.getHeader().setSimId(msg.getHeader().getSimId());
        ts.getHeader().setMessageSize(14);
        ts.getHeader().setMessageSerialNo(msg.getHeader().getMessageSerialNo());
        send(ts);
    }

    private void terminalStartTrans(Message msg){
        int res = 0;
        Qy_08 qy08 = (Qy_08)msg.getMessageContents();

        Res_08 res08 = new Res_08();
        res08.setStartRes((byte)res);
        res08.setSerialNumber(qy08.getSerialNumber());

        Message ts = new Message();
        ts.setMessageContents(res08);
        ts.setHeader(new MessageHeader());
        ts.getHeader().setMessageId(0x08);
        ts.getHeader().setSimId(msg.getHeader().getSimId());
        ts.getHeader().setMessageSize(14);
        ts.getHeader().setMessageSerialNo(msg.getHeader().getMessageSerialNo());
        send(ts);
    }

    private void terminalHeart(Message msg){

        Qy_04 qy04 = (Qy_04)msg.getMessageContents();

        System.out.println(qy04.getCsq());


        Res_04 res04 = new Res_04();

        Message ts = new Message();
        ts.setMessageContents(res04);
        ts.setHeader(new MessageHeader());
        ts.getHeader().setMessageId(0x04);
        ts.getHeader().setSimId(msg.getHeader().getSimId());
        ts.getHeader().setMessageSize(12);
        ts.getHeader().setMessageSerialNo(msg.getHeader().getMessageSerialNo());
        send(ts);
    }

    private void terminalTime(Message msg){
        int res = 0;
        Res_03 res03 = new Res_03();

        Date dt = new Date();
        String currentTime = CommonUtils.getTimeFormat(dt,"yy-MM-dd-HH-mm-ss");


        res03.setSystemDate( currentTime);

        Long longCurrentTime = dt.getTime();
        res03.setSystemTimestamp(Long.toHexString(longCurrentTime/1000));

        Message ts = new Message();
        ts.setMessageContents(res03);
        ts.setHeader(new MessageHeader());
        ts.getHeader().setMessageId(0x03);
        ts.getHeader().setSimId(msg.getHeader().getSimId());
        ts.getHeader().setMessageSize(22);
        ts.getHeader().setMessageSerialNo(msg.getHeader().getMessageSerialNo());
        send(ts);
    }

    private void terminalLogin(Message msg){
        int res = 0;

        Qy_02 qy02 = (Qy_02)msg.getMessageContents();


        Res_02 res02 = new Res_02();
        res02.setLoginRes((byte)res);

        Message ts = new Message();
        ts.setMessageContents(res02);
        ts.setHeader(new MessageHeader());
        ts.getHeader().setMessageId(0x02);
        ts.getHeader().setSimId(msg.getHeader().getSimId());
        ts.getHeader().setMessageSize(13);
        ts.getHeader().setMessageSerialNo(msg.getHeader().getMessageSerialNo());
        send(ts);
    }

    private void terminalRegister(Message msg){
        int res = 0;
        int mode = 0;
        String registerNo = String.valueOf(System.currentTimeMillis()/1000);
        Res_01 res01 = new Res_01();

        res01.setRegisterRes((byte)res);
        res01.setWorkMode((byte)mode);
        res01.setRegisterNo(registerNo);

        Message ts = new Message();
        ts.setMessageContents(res01);
        ts.setHeader(new MessageHeader());
        ts.getHeader().setMessageId(0x01);
        ts.getHeader().setSimId(msg.getHeader().getSimId());
        ts.getHeader().setMessageSize(24);
        ts.getHeader().setMessageSerialNo(msg.getHeader().getMessageSerialNo());
        redisUtil.setStr(msg.getHeader().getSimId(),registerNo);
        send(ts);
    }

}
